#include <iostream>
#include <cstring>
#include <memory>
// 套接字四件
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>
#include <unistd.h>

using namespace std;
// 设置一个全局变量gport
uint16_t _gport(8888);
#define BACKLOG 8
#define CONV(x) (struct sockaddr *)(x)

class TcpServer
{
public:
    TcpServer(int port = _gport) : _port(port), _isrunning(false)
    {
    }

    void Init()
    {
        // 创建套接字文件
        _sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (_sockfd == -1)
        {
            perror("创建套接字失败");
            exit(-1);
        }
        // 初始化套接字结构体用于绑定套接字文件，以便创建基本信息
        sockaddr_in Server;
        memset(&Server, 0, sizeof(Server));
        Server.sin_addr.s_addr = INADDR_ANY; // 需要绑定ip 此处时任何ip
        Server.sin_family = AF_INET;         // 套接字类型
        Server.sin_port = htons(_port);      // 绑定端口

        // 绑定套接字信息
        int n = bind(_sockfd, CONV(&Server), sizeof(Server));
        if (n == -1)
        {
            perror("绑定失败");
            exit(-1);
        }
        // tcp服务需要监听
        n = listen(_sockfd, BACKLOG); // BACKLOG 设置最大等待数量
        if (n == -1)
        {
            perror("监听失败:");
            exit(-1);
        }
        cout << "初始化成功" << endl;
    }
    void Start()
    {
        cout << "开始监听" << endl;
        _isrunning = true;
        while (_isrunning)
        {
            struct sockaddr_in Client; // 用户soket文件信息
            socklen_t len = sizeof(Client);
            int clfd = accept(_sockfd, CONV(&Client), &len); // 接收用户数据
            uint16_t clport = ntohs(Client.sin_port);
            string clip = inet_ntoa(Client.sin_addr);
            if (clfd < 0)
            {
                cout << "接收失败" << endl;
            }
            cout << "ip:" << clip << "端口:" << clport << endl;
            HandlerRequest(clfd);
        }
    }
        void HandlerRequest(int clfd)
    {
        char buffer[1024];
        int size = 1023;
        while (true)
        {
            int len=read(clfd,buffer,size);
            buffer[len]=0;
            string str=buffer;
            string echo= "echo";
            echo+=str;
            write(clfd,echo.c_str(),echo.size());
        }
    }

    // 三个成员变量
private:
    int _sockfd;
    uint16_t _port;
    bool _isrunning;
};